#include "daemon_runner.h"
typedef struct 
{

    char *path;
    char *args;
    pid_t pid;

}sub_process_t;

/// @brief 检查进程是否启动
/// @param process 
void daemon_runner_check_process(sub_process_t *process)
{
    //如果pid>0表示已有进程
    if(process->pid > 0)
    {
        //进行进程检测
        pid_t pid = waitpid(process->pid,NULL,WNOHANG);

        if (pid == 0)
        {
            log_info("子进程正在运行:%s(%d)",process->path,process->pid);
            return;
        }
        else if(pid > 0)
        {
            //进程结束
            log_info("子进程已结束: %s(%d)",process->path,process->pid);
        }
        else
        {
            //未知状态
            log_error("未知状态 waitpid错误");
        }
        
    }
    //要么第一次启动 要么中途挂掉 需要重新启动
    process->pid = -1;//默认给个-1 创建成功会覆盖
    pid_t pid = fork();

    if (pid == 0)
    {
        log_info("启动子进程 %s",process->path);
        execl(process->path,process->path,process->args,NULL);

        //如果子进程创建成功就去执行子进程的代码
        //没有成功执行错误
        perror("子进程创建失败");
        log_error("%s",process->path);
        
    }
    else if( pid > 0 )
    {
        process->pid = pid;
    }
    else
    {
        perror("fork错误");
    }
}



/// @brief 启动后台保护
/// @param  
void daemon_runner_start(void)
{
    // 将程序转为后台进程
    daemon(1, 0);
    // 关闭重定向
    close(STDIN_FILENO);
    close(STDOUT_FILENO);
    close(STDERR_FILENO);

    int fd_in = open("/dev/null", O_RDWR, 0666);
    if (fd_in == -1)
    {
        perror("fd_in重定向失败");
        return;
    }

    int fd_out = open("/root/gateway_txt.log", O_RDWR | O_CREAT, 0666);
    if (fd_out == -1)
    {
        perror("fd_out重定向失败");
        return;
    }

    int fd_err = open("/root/gateway_txt.log", O_RDWR | O_CREAT, 0666);
    if (fd_err == -1)
    {
        perror("fd_out重定向失败");
        return;
    }

    sub_process_t app_process = {
        .path = "/user/bin/gateway_txt",
        .args = "app",
        .pid = -1};

    sub_process_t ota_process = {     
        .path = "/user/bin/gateway_txt",
        .args = "ota",
        .pid = -1};

    while (1)
    {
        daemon_runner_check_process(&app_process);
        daemon_runner_check_process(&ota_process);
        sleep(1);
    }

}